﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace Moe_v0._1
{
    class EnWordDictionary
    {
        private static Dictionary<string, EnWordProperty> _dict = null;

        public static void InitializeDictionaryFromFile(string dictionaryFullName)
        {
            Debug.Assert(dictionaryFullName.Length > 0);
#region Code for vocabulary.txt
#if false
            using (StreamReader reader = new StreamReader(dictionaryFullName))
            {
                _dict = new Dictionary<string, EnWordProperty>();
                while (!reader.EndOfStream)
                {
                    string word = reader.ReadLine();
                    word = word.ToLower();
                    string property = reader.ReadLine();
                    bool isNoun = false;
                    bool isVerb = false;
                    bool isAdj = false;
                    if (property.Contains("n"))
                    {
                        isNoun = true;
                    }
                    if (property.Contains("v"))
                    {
                        isVerb = true;
                    }
                    if (property.Contains("a"))
                    {
                        isAdj = true;
                    }
                    _dict.Add(word, new EnWordProperty(word, isNoun, isVerb, isAdj));
                }
            }
#endif
#endregion
            using (StreamReader reader = new StreamReader(dictionaryFullName))
            {
                _dict = new Dictionary<string, EnWordProperty>();
                Regex regex = new Regex(@"(?<word>\S+)\s+(?<property>.+)");
                // \s+(?<property>.+)
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    Match match = regex.Match(line);
                    if (match.Success)
                    {
                        string word = match.Groups["word"].Value;
                        word = word.ToLower();
                        string property = match.Groups["property"].Value;
                        bool isNoun = false;
                        bool isVerb = false;
                        bool isAdj = false;
                        if (_dict.ContainsKey(word))
                        {
                            // the word already exists in the _dict, so we just update it.
                            isNoun = _dict[word].IsNoun();
                            isVerb = _dict[word].IsVerb();
                            isAdj = _dict[word].IsAdj();
                            _dict.Remove(word);
                            
                            //if (MoeDebugger.IsDebugging)
                            //{
                            //    MoeDebugger.AddDebugInfo(word);
                            //}
                        }
                        if (property.Contains("n"))
                        {
                            isNoun = true;
                        }
                        if (property.Contains("v"))
                        {
                            isVerb = true;
                        }
                        if (property.Contains("a"))
                        {
                            isAdj = true;
                        }

                        _dict.Add(word, new EnWordProperty(word, isNoun, isVerb, isAdj));
                    }
                }
            }

            // We ensure _dict is NOT null after initialization.
            Debug.Assert(_dict != null);
            if (MoeDebugger.IsDebugging)
            {
                MoeDebugger.AddDebugInfo("===EnWordDictionary::InitiralizeDictionary====");
                MoeDebugger.AddDebugInfo(_dict.Count.ToString() + " word property records are loaded.");
                MoeDebugger.AddDebugInfo("==============================================");
            }
        }

        // Returns null if the method fail to get the property of the "word".
        public static EnWordProperty GetEnWordProperty(string word)
        {
            // _dict MUST NOT be null!
            Debug.Assert(_dict != null, "Please initialize _dict before using it!!!");

            word = word.ToLower();
            if (_dict.ContainsKey(word))
            {
                if (MoeDebugger.IsDebugging)
                {
                    MoeDebugger.AddDebugInfo("===EnWordDictionary::GetEnWordPropery===");
                    MoeDebugger.AddDebugInfo(string.Format("word: {0}; noun: {1}; verb: {2}; adj: {3};",
                        word, 
                        _dict[word].IsNoun().ToString(),
                        _dict[word].IsVerb().ToString(),
                        _dict[word].IsAdj().ToString()));
                    MoeDebugger.AddDebugInfo("========================================");
                }
                return _dict[word];
            }
            else
            {
                // Fail to find the word in the dictionary, we return null to the user.
                if (MoeDebugger.IsDebugging)
                {
                    MoeDebugger.AddDebugInfo("EnWordDictionary::EnWordPropery: Fail to get the property of"
                    + "[ " + word + " ]");
                }
                return null;
            }
        }
    }
}
